package com.openatc.agent.service.impl;

import com.google.gson.*;
import com.openatc.agent.utils.TokenUtil;
import com.openatc.extend.common.aop.log.AbstractLogDataExtractor;
import com.openatc.extend.common.aop.model.WebOperationRecord;
import com.openatc.agent.utils.HttpUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import javax.servlet.ServletRequest;
import java.lang.reflect.Method;
import java.util.logging.Logger;

/**
 * @author ：panleilei
 * @description
 * @modified By：
 * @version:
 * @date ：Created in 2023/3/24 22:24
 */
public class WebOperationRecordExtractor extends AbstractLogDataExtractor {
    private static final Logger logger = Logger.getLogger(WebOperationRecordExtractor.class.getSimpleName());
    // 操作模块定义
    private static final String LOGIN_LOGOUT = "login"; // 登录/登出
    private static final String INT_MANAGER = "intersection"; // 路口管理
    private static final String ROUTE_MANAGER = "route"; // 路线管理
    private static final String USER_MANAGER = "user"; // 用户管理
    private static final String ROLE_MANAGER = "role"; // 角色管理
    private static final String ROUTE_DOWNLOAD = "route-download"; // 路线协调下载

    // 方法名
    private static final String LOGIN = "edgeLogin"; // 登录
    private static final String LOGOUT = "edgeLogout"; // 登出

    private static final String CREATE_INTERSECTION = "InsertDev"; // 新增路口
    private static final String MODIFY_INTERSECTION = "UpdateDev"; // 修改路口
    private static final String MODIFY_AGENTID_INTERSECTION = "modifyAgentid"; // 修改路口id
    private static final String DELETE_INTERSECTION = "DeleteDev"; // 删除路口

    private static final String CREATE_ROUTE = "addRoutes"; // 新增路线
    private static final String MODIFY_ROUTE = "updateRoute"; // 修改路线
    private static final String DELETE_ROUTE = "deleteRoute"; // 删除路线

    private static final String CREATE_USER = "addUser"; // 新增用户
    private static final String MODIFY_USER = "updateUserInfo"; // 修改用户
    private static final String DELETE_USER = "deleteUser"; // 删除用户

    private static final String CREATE_ROLE = "addRole"; // 新增角色
    private static final String MODIFY_ROLE = "putRole"; // 修改角色
    private static final String DELETE_ROLE = "delRole"; // 删除角色

    private static final String DOWNLOAD_ROUTE = "downloadConfigure"; // 下载路线协调方案
    private static final String DOWNLOAD_ROUTE_PATTERN = "updateRoutePattern"; // 下载干线协调方案
    private static final String DOWNLOAD_ROUTE_OPT_PATTERN= "downOptPattern"; // 保存干线协调方案

    static {
        // 登录/登出
        addMethodNameModel(LOGIN,LOGIN_LOGOUT);
        addMethodNameModel(LOGOUT,LOGIN_LOGOUT);

        addMethodNameType(LOGIN,LOGIN_INFOTYPE);
        addMethodNameType(LOGOUT,LOGOUT_INFOTYPE);
        // 路口管理
        addMethodNameModel(CREATE_INTERSECTION,INT_MANAGER);
        addMethodNameModel(MODIFY_INTERSECTION,INT_MANAGER);
        addMethodNameModel(DELETE_INTERSECTION,INT_MANAGER);
        addMethodNameModel(MODIFY_AGENTID_INTERSECTION,INT_MANAGER);

        addMethodNameType(CREATE_INTERSECTION,CREATE_INFOTYPE);
        addMethodNameType(MODIFY_INTERSECTION,MODIFY_INFOTYPE);
        addMethodNameType(MODIFY_AGENTID_INTERSECTION,MODIFY_INFOTYPE);
        addMethodNameType(DELETE_INTERSECTION,DELETE_INFOTYPE);

        // 路线管理
        addMethodNameModel(CREATE_ROUTE,ROUTE_MANAGER);
        addMethodNameModel(MODIFY_ROUTE,ROUTE_MANAGER);
        addMethodNameModel(DELETE_ROUTE,ROUTE_MANAGER);

        addMethodNameType(CREATE_ROUTE,CREATE_INFOTYPE);
        addMethodNameType(MODIFY_ROUTE,MODIFY_INFOTYPE);
        addMethodNameType(DELETE_ROUTE,DELETE_INFOTYPE);
        // 用户管理
        addMethodNameModel(CREATE_USER,USER_MANAGER);
        addMethodNameModel(MODIFY_USER,USER_MANAGER);
        addMethodNameModel(DELETE_USER,USER_MANAGER);

        addMethodNameType(CREATE_USER,CREATE_INFOTYPE);
        addMethodNameType(MODIFY_USER,MODIFY_INFOTYPE);
        addMethodNameType(DELETE_USER,DELETE_INFOTYPE);
        // 角色管理
        addMethodNameModel(CREATE_ROLE,ROLE_MANAGER);
        addMethodNameModel(MODIFY_ROLE,ROLE_MANAGER);
        addMethodNameModel(DELETE_ROLE,ROLE_MANAGER);

        addMethodNameType(CREATE_ROLE,CREATE_INFOTYPE);
        addMethodNameType(MODIFY_ROLE,MODIFY_INFOTYPE);
        addMethodNameType(DELETE_ROLE,DELETE_INFOTYPE);
        // 协调路线下载
        addMethodNameModel(DOWNLOAD_ROUTE,ROUTE_DOWNLOAD);
        addMethodNameModel(DOWNLOAD_ROUTE_PATTERN,ROUTE_DOWNLOAD);
        addMethodNameModel(DOWNLOAD_ROUTE_OPT_PATTERN,ROUTE_DOWNLOAD);

        addMethodNameType(DOWNLOAD_ROUTE,DOWNLOAD_INFOTYPE);
        addMethodNameType(DOWNLOAD_ROUTE_PATTERN,DOWNLOAD_INFOTYPE);
        addMethodNameType(DOWNLOAD_ROUTE_OPT_PATTERN,DOWNLOAD_INFOTYPE);

        addModelNameProject(LOGIN_LOGOUT,PROJECT_OPENSOURCE);
        addModelNameProject(INT_MANAGER,PROJECT_OPENSOURCE);
        addModelNameProject(ROUTE_MANAGER,PROJECT_OPENSOURCE);
        addModelNameProject(USER_MANAGER,PROJECT_OPENSOURCE);
        addModelNameProject(ROLE_MANAGER,PROJECT_OPENSOURCE);
    }


    @Override
    public WebOperationRecord extract(ProceedingJoinPoint point, Object ret) {

        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();

        WebOperationRecord record = new WebOperationRecord();

        record.setOperator(getOperatorName(methodName,point.getArgs()));
        record.setSource(HttpUtil.getIpAddress());
        record.setModel(getRecodeModel(methodName));
        record.setInfotype(getInfoType(methodName));
        record.setStatus(getStatus(ret));
        record.setRequestbody(getRequestBody(point.getArgs()));
        record.setResponsebody(getResponseBody(ret));
        record.setRequestsource(getRequestSocurce(methodName));

        return record;
    }


    /**
     * 获取方法的请求参数
     * @param args
     * @return
     */
    protected JsonElement getRequestBody(Object[] args) {
        Gson gson = new GsonBuilder().create();
        JsonArray requestBody = null;
        if (args != null && args.length != 0) {
            requestBody =  new JsonArray();
            for (Object obj : args) {
                if (obj instanceof ServletRequest) {
                    continue;
                }
                if (obj instanceof JsonElement) {
                    requestBody.add((JsonElement) obj);
                    continue;
                }
                requestBody.add(gson.toJsonTree(obj));
            }
        }
        return requestBody;
    }


    /**
     * 获取操作者
     * @param name 方法名
     * @param args 方法参数
     * @return
     */
    private String getOperatorName(String name, Object[] args) {
        // 如果是登录，需要从参数中获取用户名进行填充
        if (LOGIN.equals(name)) {
            JsonObject arg = (JsonObject) args[1];
            String user_name = arg.get("user_name").getAsString();
            return user_name;
        } else {
            return TokenUtil.getCurrentUserName();
        }
    }


}
